perm filename DEFVST[MAC,LSP] blob
sn#555014 filedate 1981-01-06 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00007 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 DEFVST -*-Mode:LispPackage:SI-*-
C00004 00003
C00008 00004
C00015 00005
C00017 00006
C00022 00007
C00025 ENDMK
C⊗;
;;; DEFVST -*-Mode:Lisp;Package:SI-*-
;;; **************************************************************************
;;; ***** NIL ****** NIL/MACLISP/LISPM Structure Definer *********************
;;; **************************************************************************
;;; ******** (c) Copyright 1980 Massachusetts Institute of Technology ********
;;; ************ this is a read-only file! (all writes reserved) *************
;;; **************************************************************************
;;; Acronym for "DEFine a Vector-like STructure"
;;; For documentation and examples, see the file LIBDOC;DEFVST DOC on the
;;; various ITS systems, and LISP:DEFVST.DOC on TOPS10/20 systems.
;;; For MacLISP, to compile NADEFVST, just do (SSTATUS FEATURE NADEFVST)
;;; at the COMPLR first.
(eval-when (eval compile)
(cond ((status nofeature MACLISP))
((status feature NADEFVST)
(sstatus feature For-NIL))
((status nofeature For-NIL)
(sstatus feature FM)
(sstatus feature FOR-MACLISP)))
)
(herald DEFVST /132)
#-FM
(globalize "DEFVST"
"CONSTRUCTOR-NAMESTRING-PREFIX"
"SELECTOR-NAMESTRING-STYLE"
"STRUCT-LET"
"STRUCT-SETF"
)
(eval-when (eval compile)
(macro lispdir (x)
(setq x (cadr x))
#+(or NADEFVST (and FM Pdp10))
`(QUOTE ((LISP) ,x))
#+Lispm
(string-append "lisp;" (get-pname x) "qfasl")
#+Multics
(catenate ">exl>lisp←dir>object" (get←pname x))
#-(or NADEFVST FM LISPM)
(string-append "lisp:" (get-pname x) "vasl")
)
(macro subload (x)
(setq x (cadr x))
`(OR (GET ',x 'VERSION) (LOAD #%(LISPDIR ,x))))
)
;; Load DEFVSX and DEFMAX now to get their "globalizations"
;; Load EXTEND before DEFVSX so that CLASS system will be available
#-For-NIL
(eval-when (eval compile load)
(subload EXTEND) ;Bring these guys in before DEFVSX,
(subload EXTMAC) ; so that the CLASS system will be
(subload VECTOR) ; alive by then.
(subload DEFVSX)
)
#+NADEFVST
(eval-when (eval compile)
(subload EXTEND) ;Bring these guys in before DEFVSX,
(subload EXTMAC) ; so that the CLASS system will be
(subload VECTOR) ; alive by then.
(subload DEFVSX)
(subload DEFSETF)
(subload UMLMAC))
)
(declare (special DEFMACRO-DISPLACE-CALL
CONSTRUCTOR-NAMESTRING-PREFIX
SELECTOR-NAMESTRING-STYLE
STRUCT-CLASS
STRUCT=INFO-CLASS
|defvst-typchk/||
|defvst-construction/||)
#M (*expr |defvst-construction/|| |defvst-construction-1/||
|defvst-typchk/|| )
#M (*lexpr TO-VECTOR))
(MAPC '(LAMBDA (X Y) (AND (NOT (BOUNDP X)) (SET X Y)))
'(SELECTOR-NAMESTRING-STYLE CONSTRUCTOR-NAMESTRING-PREFIX )
'(|-| |CONS-A-| ))
#M(declare (own-symbol DEFVST STRUCT-LET STRUCT-SETF))
#+NADEFVST (includef '((NILCOM) DEFVSY))
#+NADEFVST (includef '((NILCOM) DEFVSX))
;; FOO! to prevent circularities when compiling
#M
(eval-when (compile)
(do ((i 0 (1+ i))
(l '(VERS NAME CNSN SIZE INIS CLSS) (cdr l))
(z))
((null l))
(setq z (symbolconc 'STRUCT=INFO- (car l)))
(eval `(DEFMACRO ,z (X) `(SI:XREF ,X ,,i))))
)
;;;; DEFVST macro
(defmacro (DEFVST defmacro-displace-call () ) (sname &rest selkeys)
(LET ((NKEYS 0)
(SELECTOR-NAMESTRING-STYLE SELECTOR-NAMESTRING-STYLE)
(CONSTRUCTOR-NAMESTRING-PREFIX CONSTRUCTOR-NAMESTRING-PREFIX)
CONSTRUCTOR-NAME RESTKEY RESTSIZEFORM RESTP SELINIS MAC-ARG-NM
TMP)
(DECLARE (FIXNUM I NKEYS))
(AND (NOT (ATOM SNAME))
(SETQ SNAME (PROG2 () (CAR SNAME)
(DO L (CDR SNAME) (CDDR L) (NULL L)
(OR (EQ (CAR L) 'DEFMACRO-DISPLACE-CALL)
(SET (CAR L) (EVAL (CADR L))))) )))
(AND (OR (NULL SNAME) (NOT (SYMBOLP SNAME)))
(ERROR "Bad args - DEFVST" (CONS SNAME SELKEYS)))
(SETQ NKEYS (LENGTH SELKEYS))
(COND ((SETQ TMP (MEMQ '&REST SELKEYS))
(SETQ NKEYS (- NKEYS (LENGTH TMP))
RESTKEY (CADR TMP)
RESTSIZEFORM (CADDR TMP))
(AND (OR (NOT (SYMBOLP RESTKEY)) (NULL RESTSIZEFORM))
(ERROR "Lossage in &REST variable - DEFVST" SELKEYS))))
(COND ((GET SNAME 'STRUCT=INFO)
(TERPRI MSGFILES)
(PRINC "Warning! Redefining the STRUCTURE " MSGFILES)
(PRIN1 SNAME MSGFILES)))
(SETQ MAC-ARG-NM (INTERN (SYMBOLCONC SNAME '|-MACRO-ARG|))
CONSTRUCTOR-NAME SNAME)
(AND CONSTRUCTOR-NAMESTRING-PREFIX
(SETQ CONSTRUCTOR-NAME
(INTERN (SYMBOLCONC CONSTRUCTOR-NAMESTRING-PREFIX SNAME))))
;RESTP and SELINIS start out null here
(DO ( (I 1 (1+ I))
(L SELKEYS (CDR L))
INIFORM TYP /=-/:-COUNT KEYNM SELNM )
( (OR (NULL L) RESTP) )
(COND ((ATOM (SETQ KEYNM (CAR L)))
(COND ((EQ KEYNM '&REST)
(SETQ KEYNM RESTKEY RESTP 'T)
(AND (NOT (EQ RESTKEY (CADR L)))
(ERROR '|&REST lossage DEFVST|)))
((NOT (SYMBOLP KEYNM))
(ERROR '|KEY NAME NOT A SYMBOL - DEFVST| KEYNM)))
(SETQ INIFORM () ))
('T (AND (OR (NULL (SETQ KEYNM (CAR KEYNM)))
(NOT (SYMBOLP KEYNM)))
(ERROR '|Bad key-list - DEFVST| SELKEYS))
(COND ((ATOM (SETQ TMP (CDAR L))) (SETQ INIFORM () ))
('T (SETQ /=-/:-COUNT 0 )
(AND (NULL (CDR TMP)) ;Allow LISPM-
(SETQ TMP `(= ,(car tmp)))) ; style inits
(COND ((SETQ TYP (MEMQ '|:| TMP))
(SETQ /=-/:-COUNT 1)
(SETQ TYP (COND ((ATOM (CADR TYP))
(LIST (CADR TYP)))
((CADR TYP))))))
(SETQ INIFORM
(COND ((SETQ INIFORM (MEMQ '= TMP))
(SETQ /=-/:-COUNT (1+ /=-/:-COUNT))
(CADR INIFORM))
(TYP (CDR (OR (ASSQ
(CAR TYP)
'((FIXNUM . 0)
(FLONUM . 0.0)
(BIGNUM . 500000000000000000000.)
(LIST . () )
(SYMBOL . FOO)
(ARRAY . () )
(HUNK . () )
))
#+For-NIL (ASSQ (CAR TYP)
'((SMALL-FLONUM 0.0)
(PAIR . '(() ))
;fix... (VECTOR . #() )
(STRING . "" )))
)))))
(AND (NOT (= /=-/:-COUNT 0))
(SETQ INIFORM (CONS INIFORM TYP)))
(COND ((NOT (= (* 2 /=-/:-COUNT) (LENGTH TMP)))
(PRINT (CAR L) MSGFILES)
(PRINC "Options list has options not yet coded ")))
))
))
(SETQ SELNM KEYNM)
(AND SELECTOR-NAMESTRING-STYLE
(SETQ SELNM (INTERN (SYMBOLCONC SNAME
SELECTOR-NAMESTRING-STYLE
KEYNM))))
(COND ((NOT RESTP)
;; INIFORM = (<initialization-form> <restrictions>...)
(PUSH `(,keynm ,selnm ,.iniform) SELINIS))
('T (SETQ RESTP `(,keynm ,selnm ,restsizeform))
(OR (= I (1+ NKEYS)) (ERROR '|Missed &REST key?| I)))))
`(EVAL-WHEN (EVAL COMPILE LOAD)
#+FM (defprop |defvst-initialize/|| #.(lispdir DEFVSY) AUTOLOAD)
(AND (STATUS FEATURE COMPLR)
(SPECIAL ,(symbolconc sname '/-CLASS)))
(|defvst-initialize/||
',sname
',constructor-name
,nkeys
',(to-vector (cons restp (nreverse selinis)))
1
;; Leave commented out until old dumps die out -- RWK 29 December 1980
;; ,(and (filep infile) `',(truename infile))
)
;; The next should be flushed when the above is un-commented-out
;; RWK -- 29 December 1980
,@(and (filep infile)
`((setf (get (si:class-plist (get ',sname 'CLASS))
':SOURCE-FILE)
',(truename infile))))
,.(if restp
`((DEFPROP ,(cadr restp)
(,sname ,(1+ nkeys) &REST)
SELECTOR)))
',sname)))
;;;; STRUCT-LET and STRUCT-SETF
;;; E.g. (STRUCT-LET ((structure-name struct-object-to-be-destructured)
;; (var slot-name) ; or,
;; (var-named-same-as-slot) ; or,
;; var-named-same-as-slot
;; ...)
;; . body)
(defmacro (STRUCT-LET defmacro-displace-call '|defvst-construction/||)
((struct-name str-obj) bvl &rest body)
(let (var slot-name accessor)
(setq bvl (mapcar
'(lambda (e)
(if (atom e) (setq e `(,e ,e)))
(desetq (var slot-name) e)
(or slot-name (setq slot-name var))
(setq accessor (symbolconc struct-name '/- slot-name))
`(,var (,accessor ,str-obj)))
bvl))
`(LET ,bvl ,.body)))
;;; E.g. (STRUCT-SETF (structure-name object) (slot-name value) ...)
(defmacro (STRUCT-SETF defmacro-displace-call '|defvst-construction/||)
((str-name str-obj) &rest l &aux slot-name accessor val)
`(PROGN ,. (mapcar
'(lambda (x)
(desetq (slot-name val) x)
(setq accessor (symbolconc str-name '/- slot-name))
`(SETVST (,accessor ,str-obj) ,val))
l)))
;;;; Structure Printer
;; Someday, hack printing of &REST stuff
(DEFVAR SI:PRINLEVEL-EXCESS '|#|)
(DEFVAR SI:PRINLENGTH-EXCESS '|...|)
(DEFMETHOD* (PRINT STRUCT-CLASS) (OB STREAM DEPTH SLASHIFYP)
(DECLARE (FIXNUM DEPTH))
(SETQ DEPTH (1+ DEPTH))
(COND ((AND PRINLEVEL (NOT (< DEPTH PRINLEVEL)))
(PRINC SI:PRINLEVEL-EXCESS STREAM))
(T (SI:CHECK-DEFVST-VERSION (SI:CLASS-NAME (CLASS-OF OB)))
(LET* ((TYP (SI:CLASS-NAME (CLASS-OF OB)))
(INFO (GET TYP 'STRUCT=INFO)))
(COND ((NULL INFO) (SI:PRINT-EXTEND-MAKNUM OB STREAM))
(T (PRINC '|#{| STREAM)
(DO ((Z (SI:LISTIFY-STRUCT-FOR-PRINT OB TYP INFO)
(CDR Z))
(N 0 (1+ N))
(FIRST 'T ()))
((NULL Z))
(DECLARE (FIXNUM N))
(OR FIRST (TYO #\SPACE STREAM))
(PRINT-OBJECT (CAR Z) DEPTH SLASHIFYP STREAM)
(COND ((AND PRINLENGTH (NOT (< N PRINLENGTH)))
(TYO #\SPACE STREAM)
(PRINC SI:PRINLENGTH-EXCESS STREAM)
(RETURN ()))))
(TYO #/} stream)))))))
(DEFMETHOD* (SPRINT STRUCT-CLASS) (OB N M)
(DECLARE (SPECIAL L N M))
(SI:CHECK-DEFVST-VERSION (SI:CLASS-NAME (CLASS-OF OB)))
(LET* ((TYP (SI:CLASS-NAME (CLASS-OF OB)))
(INFO (GET TYP 'STRUCT=INFO)))
(COND ((NULL INFO) (SI:PRINT-EXTEND-MAKNUM OB OUTFILES))
(T (LET ((Z (SI:LISTIFY-STRUCT-FOR-PRINT OB TYP INFO)))
(COND ((> (- (GRCHRCT) 3.) (GFLATSIZE Z))
(PRIN1 OB))
(T (PRINC '|#{|)
(PRIN1 (CAR Z))
(COND ((CDR Z)
(TYO #\SPACE)
(SETQ N (GRCHRCT) M (1+ M))
(DO ((L (CDR Z)))
((NULL L))
(GRINDFORM 'LINE)
(GRINDFORM 'CODE)
(COND (L (INDENT-TO N))))))
(TYO #/}))))))))
;; Sure, this could do less consing, if it really wanted to. But who
;; wants to trouble to write such hairy code?
(DEFUN SI:LISTIFY-STRUCT-FOR-PRINT (OB TYP INFO)
(LET* ((SUPPRESS (GET TYP 'SUPPRESSED-COMPONENT-NAMES))
(INIS (STRUCT=INFO-INIS INFO)))
(DO ((I 1 (1+ I))
(N (*:EXTEND-LENGTH INIS)) ;actually, VECTOR-LENGTH
(THE-LIST (LIST TYP)))
((NOT (< I N)) (NREVERSE THE-LIST))
;The (1+ i)th component of INIS corresponds to the ith
;component of OB. The 0th component of INIS corresponds
;to the &REST stuff which this code doesn't address.
(LET* (((NAME SELECTOR INIT) (*:XREF INIS I)) ;actually, VREF
(VAL (*:XREF OB (CADR (GET SELECTOR 'SELECTOR)))))
(COND ((MEMQ NAME SUPPRESS))
;;Incredible kludge to avoid printing defaulted vals
((OR (AND (NULL INIT) (NULL VAL))
(AND (|constant-p/|| INIT)
(EQUAL VAL (EVAL INIT)))
(AND (PAIRP INIT)
(EQ (CAR INIT) 'QUOTE)
(EQUAL VAL (CADR INIT)))))
(T (PUSH NAME THE-LIST)
(PUSH VAL THE-LIST)))))))
(defmethod* (EQUAL struct-class) (ob other)
(or (eq ob other) ;generally, this will have already been done
(let ((ty1 (struct-typep ob))
(ty2 (struct-typep other)))
(cond ((or (null ty1) (null ty2) (not (eq ty1 ty2))) () )
((si:component-equal ob other))))))
(defmethod* (SUBST struct-class) (ob a b)
(si:subst-into-extend ob a b))
(defmethod* (SXHASH struct-class) (ob)
(si:hash-Q-extend ob #.(sxhash 'STRUCT)))
(defmethod* (DESCRIBE struct-class) (ob stream level)
(cond ((not (> level si:describe-max-level))
(si:check-DEFVST-version (struct-typep ob))
(let* ((typ (struct-typep ob))
(inis (struct=info-inis (get typ 'struct=info)))
(ninis (*:extend-length inis))
(suppress (get typ 'suppressed-component-names)))
(format stream '|}%}vTThe named structure has STRUCT-TYPEP }S|
level typ)
(cond (suppress
(format stream '|}%}vtThese component names are suppressed: }S|
level suppress)))
(format stream '|}%}vtThe }D. component names and contents are:|
level (1- ninis))
(do ((i 1 (1+ i)) (default () ()))
((not (< i ninis)))
(let* (((name selector init) (*:xref inis i))
(val (*:xref ob (cadr (get (cadr (*:xref inis i))
'selector)))))
(cond ((or (and (null init) (null val))
(and (|constant-p/|| init)
(equal val (eval init)))
(and (pairp init)
(eq (car init) 'quote)
(equal val (cadr init))))
(setq default 'T)))
(format stream '|}%}vt }S: }S }:[}; [default]}]|
level (car (*:xref inis i)) val default)))
(cond ((*:xref inis 0)
(format stream '|}%}vt&REST part hasn't been Described.|
level)))))))